home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / ASSOCIAT.C next >
C/C++ Source or Header  |  1992-09-29  |  11KB  |  296 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12.  
  13. #ifndef ASSOCIATIONC
  14. #define ASSOCIATIONC
  15.  
  16. #include <cool/Association.h>
  17.  
  18. // compare_keys_s
  19. template <class Ktype, class Vtype>
  20. //##Key_Compare CoolAssociation<Ktype,Vtype>::compare_keys_s = &CoolAssociation_keys_eql;
  21. Boolean (*CoolAssociation<Ktype,Vtype>::compare_keys_s)(const Ktype&, const Ktype&) = &CoolAssociation_keys_eql;
  22.  
  23. // compare_values_s;
  24. template <class Ktype, class Vtype>
  25. //##Value_Compare CoolAssociation<Ktype,Vtype>::compare_values_s = &CoolAssociation_values_eql;
  26. Boolean (*CoolAssociation<Ktype,Vtype>::compare_values_s)(const Vtype&, const Vtype&) = &CoolAssociation_values_eql;
  27.  
  28. // CoolAssociation -- Empty constructor for the CoolAssociation class
  29. // Input:         None
  30. // Output:        None
  31.  
  32. template <class Ktype, class Vtype>
  33. CoolAssociation<Ktype,Vtype>::CoolAssociation() {
  34. }
  35.  
  36.  
  37. // CoolAssociation -- constructor that specifies number of elements
  38. // Input:         Number of elements of Type T
  39. // Output:        None
  40.  
  41. template <class Ktype, class Vtype>
  42. CoolAssociation<Ktype,Vtype>::CoolAssociation(size_t n)
  43.  : CoolVector< CoolPair<Ktype,Vtype> >(n)
  44. {
  45. }
  46.  
  47.  
  48. // CoolAssociation -- constructor that specifies number of elements and storage
  49. // Input:         Pointer to storage and number of elements of Type T
  50. // Output:        None
  51.  
  52. template <class Ktype, class Vtype>
  53. CoolAssociation<Ktype,Vtype>::CoolAssociation(void* s,size_t n)
  54.  : CoolVector< CoolPair<Ktype,Vtype> >(s,n)
  55. {
  56. }
  57.  
  58.  
  59. // CoolAssociation -- constructor for reference to another CoolAssociation object
  60. // Input:         CoolAssociation reference
  61. // Output:        None
  62.  
  63. template <class Ktype, class Vtype>
  64. CoolAssociation<Ktype,Vtype>::CoolAssociation(const CoolAssociation<Ktype,Vtype>& a)
  65.  : CoolVector< CoolPair<Ktype,Vtype> >(a)
  66. {
  67. }
  68.  
  69.  
  70. // CoolAssociation -- Destructor (not inline because it's virtual)
  71. // Input:         None
  72. // Output:        None
  73.  
  74. template <class Ktype, class Vtype>
  75. CoolAssociation<Ktype,Vtype>::~CoolAssociation() {;}
  76.  
  77.  
  78. // set_key_compare -- Set the compare function for the key of the pair
  79. // Input:             Pointer to new function
  80. // Output:            None
  81.  
  82. template <class Ktype, class Vtype>
  83. void CoolAssociation<Ktype,Vtype>::set_key_compare(/*Key_Compare##*/Boolean (*cf)(const Ktype&, const Ktype&)) {
  84.   if (cf == NULL)
  85.     this->compare_keys_s=&CoolAssociation_keys_eql; // Default equal   
  86.   else
  87.     this->compare_keys_s = cf;
  88. }
  89.  
  90. // set_value_compare -- Set the compare function for the value of the pair
  91. // Input:               Pointer to new function
  92. // Output:              None
  93.  
  94. template <class Ktype, class Vtype>
  95. void CoolAssociation<Ktype,Vtype>::set_value_compare(/*Value_Compare##*/Boolean (*cf)(const Vtype&, const Vtype&)) {
  96.   if (cf == NULL)
  97.     this->compare_values_s = &CoolAssociation_values_eql; // Default
  98.   else
  99.     this->compare_values_s = cf;
  100. }
  101.  
  102. // find -- Find first occurence of element in an CoolAssociation
  103. // Input:  Element value searching for
  104. // Output: TRUE/FALSE; current_position updated when success
  105.  
  106. template <class Ktype, class Vtype>
  107. Boolean CoolAssociation<Ktype,Vtype>::find (const Ktype& key) {
  108.   size_t i = this->number_elements;
  109.   while (i > 0) { // Search most recent first
  110.     --i;
  111.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  112.       this->curpos = i;                // Update current position if found
  113.       return TRUE;                // Return success
  114.     }
  115.   }
  116.   return FALSE;                    // Return failure
  117. }
  118.  
  119.  
  120. // get -- Get the associated value for a key in the CoolAssociation; return TRUE 
  121. //        and modify the given value variable if the key is found, otherwise 
  122. //        return FALSE and do not modify the value variable
  123. // Input:  Reference to a key, reference to a value 
  124. // Output: TRUE or FALSE
  125.  
  126. template <class Ktype, class Vtype>
  127. Boolean CoolAssociation<Ktype,Vtype>::get (const Ktype& key, Vtype& value) {
  128.   size_t i = this->number_elements;
  129.   while (i > 0) { // Search most recent first
  130.     --i;
  131.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  132.       value = this->data[i].second();        // Modify value only if found
  133.       return TRUE;                // Return success
  134.     }
  135.   }
  136.   return FALSE;                    // Return failure
  137. }
  138.  
  139.  
  140. // get_key -- Get the associated key for a value in the CoolAssociation; return 
  141. //            TRUE and modify the given key variable if the value is found, 
  142. //            otherwise return FALSE and do not modify the value variable
  143. // Input:     Reference to a value, reference to a key 
  144. // Output:    TRUE or FALSE
  145.  
  146. template <class Ktype, class Vtype>
  147. Boolean CoolAssociation<Ktype,Vtype>::get_key (const Vtype& value, Ktype& key) const {
  148.   size_t i = this->number_elements;
  149.   while (i > 0) { // Search most recent first
  150.    --i;
  151.    if ((*this->compare_values_s)(this->data[i].get_second(), value) == TRUE) {
  152.      key = this->data[i].first();        // Modify key only if found
  153.      return TRUE;                // Return success
  154.    }
  155.   }
  156.   return FALSE;                    // Return failure
  157. }
  158.  
  159.  
  160. // remove() -- Remove the pair at the current position and return the 
  161. //             value associated with that pair. Order is not preserved.
  162. // Input:      None.
  163. // Output:     Value of the removed pair, returned by value.
  164.  
  165. template <class Ktype, class Vtype>
  166. Vtype CoolAssociation<Ktype,Vtype>::remove () {
  167.   if (this->curpos == INVALID) this->remove_error("CoolPair");
  168.   Vtype value = this->data[this->curpos].second(); // Copy value removed
  169.   this->number_elements--;            // Update element count
  170.   if (this->curpos == this->number_elements)    // If past end of vector
  171.     this->curpos = INVALID;            // Invalidate current position
  172.   else                        // fill hole with last elmt
  173.     this->data[this->curpos] = this->data[this->number_elements]; 
  174.   return value;                    // Return removed item
  175. }
  176.  
  177. // remove (key) -- Search for key and remove the pair associated with it, 
  178. //                 if found, and return TRUE; otherwise return FALSE
  179. // Input:          Reference to a key
  180. // Output:         TRUE or FALSE
  181.  
  182. template <class Ktype, class Vtype>
  183. Boolean CoolAssociation<Ktype,Vtype>::remove (const Ktype& key) {
  184.   if (this->find(key)) {            // Search for pair with key
  185.     this->remove();                // Remove and reset curpos
  186.     return TRUE;                // Return success/failure
  187.   }
  188.   else
  189.     return FALSE;                
  190. }
  191.  
  192. // put -- Add a key-value pair to the CoolAssociation; if the key already exists,
  193. //        replace its associated value in the CoolAssociation; return TRUE if 
  194. //        successful
  195. // Input:  Reference to a key, reference to a value
  196. // Output: TRUE or FALSE
  197.  
  198. template <class Ktype, class Vtype>
  199. Boolean CoolAssociation<Ktype,Vtype>::put (const Ktype& key, const Vtype& value) {
  200.   size_t i = this->number_elements;
  201.   while (i > 0) { // Search most recent first
  202.     --i;
  203.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  204.       this->data[i].set_second(value);        // Update value if found
  205.       this->curpos = i;                // Update current position
  206.       return TRUE;                // Return success
  207.     }
  208.   }
  209.   if (this->number_elements == this->size) {    // If not enough memory    
  210.     if (this->alloc_size == INVALID) {        // If not allowed to grow
  211. #if ERROR_CHECKING
  212.       //RAISE (Error, SYM(CoolAssociation), SYM(Static_Size)),
  213.       printf ("CoolAssociation<%s,%s>::put(): Static-size CoolAssociation.\n",
  214.               #Ktype,#Vtype);
  215. #endif
  216.       return FALSE;                // Return failure flag
  217.     }
  218.     CoolPair<Ktype,Vtype>* temp;        // Temporary storage
  219.     if (this->growth_ratio != 0.0)         // If growth ratio specified
  220.       this->size = (size_t)(this->size * (1.0 + growth_ratio)); // New size
  221.     else
  222.       this->size += alloc_size;            // Update vector size
  223.     temp = new CoolPair<Ktype,Vtype>[this->size];    // Allocate storage
  224.     for (size_t i = 0; i < this->length(); i++)    // For all elements
  225.       temp[i] = this->data[i];            // Copy data
  226.     delete [] this->data;            // Free up old memory
  227.     this->data = temp;                // Assign new memory block
  228.   }
  229.   this->curpos = this->length();        // Set current position
  230.   this->data[this->length()].set_first(key);    // Set the key (first) value
  231.   this->data[this->length()].set_second(value); // Set the value (second)
  232.   this->number_elements++;            // Increment element count
  233.   return TRUE;                    // Return success status
  234. }
  235.  
  236.  
  237. // operator== -- Compare the elements of two CoolAssociations of Type Type using
  238. //               the Compare pointer to funtion (default is ==). If one 
  239. //               CoolAssociation has more elements than another CoolAssociation, 
  240. //               then result is FALSE
  241. // Input:        Reference to CoolAssociation object
  242. // Output:       TRUE/FALSE
  243.  
  244. template <class Ktype, class Vtype>
  245. Boolean CoolAssociation<Ktype,Vtype>::operator==
  246.         (const CoolAssociation<Ktype,Vtype>& a) const {
  247.   if (this->number_elements != a.number_elements) // If not same number
  248.     return FALSE;                  // Then not equal
  249.   for (size_t i = 0; i < this->number_elements; i++) { // For each element
  250.     for (size_t j = 0; j < a.number_elements; j++) {
  251.       if ((*this->compare_keys_s)(this->data[i].get_first(),
  252.                   a.data[j].get_first()) == TRUE) {
  253.     if ((*this->compare_values_s) (this->data[i].second(),
  254.                        a.data[j].second()) == TRUE)
  255.       goto match;                // Match
  256.     return FALSE;                // Values different
  257.       }
  258.     }
  259.     return FALSE;                // Key not found
  260.   match: ;
  261.   }
  262.   return TRUE;                    // All are equal
  263. }
  264.  
  265. // operator<< -- Overload the output operator for reference to CoolAssociation
  266. // Input:        ostream reference, CoolAssociation reference
  267. // Output:       CoolAssociation data is output to ostream
  268.  
  269. template <class Ktype, class Vtype>
  270. ostream& operator<< (ostream& os, const CoolAssociation<Ktype,Vtype>& v) {
  271.   return operator<< (os, (const CoolVector< CoolPair<Ktype,Vtype> >&) v);
  272. }
  273.  
  274.  
  275. // keys_eql -- Compare two keys to see if they are equal using operator==
  276. // Input:      Two Ktype references
  277. // Output:     TRUE or FALSE
  278.  
  279. template <class Ktype>
  280. Boolean CoolAssociation_keys_eql (const Ktype& k1, const Ktype& k2) {
  281.   return (k1 == k2);
  282. }
  283.  
  284.  
  285. // values_eql -- Compare two values to see if they are equal using operator==
  286. // Input:        Two Vtype references
  287. // Output:       TRUE or FALSE
  288.  
  289. template <class Vtype>
  290. Boolean CoolAssociation_values_eql(const Vtype& v1,const Vtype& v2) {
  291.   return (v1 == v2);
  292. }
  293.  
  294. #endif // ASSOCIATIONC
  295.  
  296.